package com.traveldream.entity_managers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;

import com.traveldream.entities.Excursion;
import com.traveldream.entities.Flight;
import com.traveldream.entities.Hotel;
import com.traveldream.entities.Place;

/**
 * Con EntityManager intendo creare delle classi che 
 * facciano da interfaccia per le entity e che quindi
 * permettano di creare aggiornare rimuovere visualizzare 
 * le entity
 */
@Stateless
public class ProductManagerBean implements ProductManager {
	
	// bisogna indicare che si usa la persistenza configurata nel package Common
	@PersistenceContext(unitName="TravelDreamCommon")
    EntityManager em;
    
	@Override
    public Excursion create(Excursion excursion) {
    	// persist & flush em
        em.persist(excursion.getProduct());
        em.persist(excursion);
        em.flush();
        em.refresh(excursion);
        // return persisted object
        return excursion;
    }
    
	@Override
    public Flight create(Flight flight){
		// persist & flush em
		em.persist(flight.getProduct());
        em.persist(flight);
        em.flush();
        em.refresh(flight);
        // return persisted object
        return flight;
    }
	
	@Override
    public Hotel create(Hotel hotel){
		// persist & flush em
		em.persist(hotel.getProduct());
        em.persist(hotel);
        em.flush();
        em.refresh(hotel);
        // return persisted object
        return hotel;
    }
    
	@Override
	public Excursion findExcursion(int id) {
    	return  em.find(Excursion.class, id);
    }
    
	@Override
    public Hotel findHotel(int id) {
    	return em.find(Hotel.class, id);
    }
    
	@Override
    public Flight findFlight(int id) {
    	return em.find(Flight.class, id);
    }
    
	@Override
    public List<Excursion> findAllExcursions()
    {
    	Query query = em.createNamedQuery("Excursion.findAll",Excursion.class);
    	List<Excursion> results=new ArrayList<Excursion>();
   		for( Object o : query.getResultList() ) 
   			results.add((Excursion)o);
		return results;
    }
    
	@Override
    public List<Hotel> findAllHotels()
    {
    	Query query = em.createNamedQuery("Hotel.findAll",Excursion.class);
    	List<Hotel> results=new ArrayList<Hotel>();
   		for( Object o : query.getResultList() ) 
   			results.add((Hotel)o);
		return results;
    }
    
	@Override
    public List<Flight> findAllFlights()
    {
    	Query query = em.createNamedQuery("Flight.findAll",Excursion.class);
    	List<Flight> results=new ArrayList<Flight>();
   		for( Object o : query.getResultList() ) 
   			results.add((Flight)o);
		return results;   
	}
    
	@Override
	public Excursion update(Excursion excursion) {
		em.merge(excursion.getProduct());
		return em.merge(excursion);
	}
	
	@Override
	public Flight update(Flight flight) {
		em.merge(flight.getProduct());
		return em.merge(flight);
	}

	@Override
	public Hotel update(Hotel hotel) {
		em.merge(hotel.getProduct());
		return em.merge(hotel);
	}

	@Override
	public boolean delete(int id) {
		Excursion e=findExcursion(id);
		if( e!=null ) {
			em.remove(e);
			em.remove(e.getProduct());
			return true;
		}
		Hotel h=findHotel(id);
		if( h!=null ) {
			em.remove(h);
			em.remove(h.getProduct());
			return true;
		}
		Flight f=findFlight(id);
		if( f!=null ) {
			em.remove(f);
			em.remove(f.getProduct());
			return true;
		}
		return false;
	}

	@SuppressWarnings({ "deprecation"})
	@Override
	public List<Flight> findFlightByDates(Date start, Date end) {
		List<Flight> results=new ArrayList<Flight>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Flight.findBeetwenDates",Flight.class).setParameter("start",start).setParameter("end", end);
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		}
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Flight.findByEndingDate",Flight.class).setParameter("end", end); 
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		} else { //end==null
			start.setDate(start.getDate()-1);
			Query query = em.createNamedQuery("Flight.findByStartingDate",Flight.class).setParameter("start", start);
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		}
		return results;
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<Hotel> findHotelByDates(Date start, Date end) {
		List<Hotel> results=new ArrayList<Hotel>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Hotel.findBeetwenDates",Hotel.class).setParameter("start",start).setParameter("end", end);
			for( Object o : query.getResultList() ) 
				results.add((Hotel)o);
		}
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Hotel.findByEndingDate",Hotel.class).setParameter("end", end,TemporalType.DATE);
			for( Object o : query.getResultList() ) 
				results.add((Hotel)o);
		} else { //end==null
			start.setDate(start.getDate()-1);
			Query query = em.createNamedQuery("Hotel.findByStartingDate",Hotel.class).setParameter("start", start,TemporalType.DATE);
			for( Object o : query.getResultList() ) 
				results.add((Hotel)o);
		}
		return results;
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<Excursion> findExcursionByDates(Date start, Date end) {
		List<Excursion> results=new ArrayList<Excursion>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Excursion.findBeetwenDates",Excursion.class).setParameter("start",start).setParameter("end", end);
			for( Object o : query.getResultList() ) 
				results.add((Excursion)o);
		}
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Excursion.findByEndingDate",Excursion.class).setParameter("end", end);
			for( Object o : query.getResultList() ) 
				results.add((Excursion)o);
		} else { //end==null
			start.setDate(start.getDate()-1);
			Query query = em.createNamedQuery("Excursion.findByStartingDate",Excursion.class).setParameter("start", start);
			for( Object o : query.getResultList() ) 
				results.add((Excursion)o);
		}
		return results;
	}

	@Override
	public List<Flight> findFlightByArrivalPlace(Place arrivalPlace) {
		Query query = em.createNamedQuery("Flight.findByArrivalPlace",Flight.class).setParameter("placeName", arrivalPlace.getName());
		List<Flight> results=new ArrayList<Flight>();
   		for( Object o : query.getResultList() ) 
   			results.add((Flight)o);
		return results;
	}

	@Override
	public List<Flight> findFlightByDeparturePlace(Place departurePlace) {
		Query query = em.createNamedQuery("Flight.findByDeparturePlace",Flight.class).setParameter("placeName", departurePlace.getName());
		List<Flight> results=new ArrayList<Flight>();
   		for( Object o : query.getResultList() ) 
   			results.add((Flight)o);
		return results;
	}

	@Override
	public List<Hotel> findHotelByPlace(Place p) {
		Query query = em.createNamedQuery("Hotel.findByPlace",Hotel.class).setParameter("placeName", p.getName());
		List<Hotel> results=new ArrayList<Hotel>();
   		for( Object o : query.getResultList() ) 
   			results.add((Hotel)o);
		return results;
	}

	@Override
	public List<Excursion> findExcursionByPlace(Place p) {
		Query query = em.createNamedQuery("Excursion.findByPlace",Excursion.class).setParameter("placeName", p.getName());
		List<Excursion> results=new ArrayList<Excursion>();
   		for( Object o : query.getResultList() ) 
   			results.add((Excursion)o);
		return results;
	}	
	

	@SuppressWarnings("deprecation")
	@Override
	public List<Flight> findFlightByDatesAndPlace(Date start, Date end,Place arrivalPlace) {
		List<Flight> results=new ArrayList<Flight>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Flight.findBeetwenDatesByPlace",Flight.class)
							.setParameter("start",start)
							.setParameter("end", end)
							.setParameter("placeName",arrivalPlace.getName());
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		}
		/* non mi servono
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Flight.findByEndingDate",Flight.class).setParameter("end", end); 
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		} else { //end==null
			start.setDate(start.getDate()-1);
			Query query = em.createNamedQuery("Flight.findByStartingDate",Flight.class).setParameter("start", start);
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		}
		*/
		return results;
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<Hotel> findHotelByDatesAndPlace(Date start, Date end,Place p) {
		List<Hotel> results=new ArrayList<Hotel>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Hotel.findBeetwenDatesByPlace",Hotel.class)
							.setParameter("start",start)
							.setParameter("end", end)
							.setParameter("placeName", p.getName());
			for( Object o : query.getResultList() ) 
				results.add((Hotel)o);
		}
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Hotel.findByEndingDate",Hotel.class).setParameter("end", end,TemporalType.DATE);
			for( Object o : query.getResultList() ) 
				results.add((Hotel)o);
		} else { //end==null
			start.setDate(start.getDate()-1);
			Query query = em.createNamedQuery("Hotel.findByStartingDate",Hotel.class).setParameter("start", start,TemporalType.DATE);
			for( Object o : query.getResultList() ) 
				results.add((Hotel)o);
		}
		return results;
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<Excursion> findExcursionByDatesAndPlace(Date start, Date end,Place p) {
		List<Excursion> results=new ArrayList<Excursion>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Excursion.findBeetwenDatesByPlace",Excursion.class)
							.setParameter("start",start)
							.setParameter("end", end)
							.setParameter("placeName", p.getName());
			for( Object o : query.getResultList() ) 
				results.add((Excursion)o);
		}
		return results;
	}
}
